#!/usr/bin/python
# -*- coding: UTF-8 -*-

import numpy as np
import os, sys, datetime, math
from skimage import feature, color
from skimage import transform as tf
from skimage.measure import find_contours

import sys
import os, random, colorsys, datetime, cv2
########### Color_Splash ##########
import skimage.draw
from skimage import data,color
import skimage.transform

def color_splash(image, mask):
    gray = skimage.color.gray2rgb(skimage.color.rgb2gray(image)) * 255
    mask = (np.sum(mask, -1, keepdims=True) >= 1)
    if mask.shape[0] > 0:
        splash = np.where(mask, image, gray).astype(np.uint8)
        # splash = np.where(mask, product, image).astype(np.uint8)
    else:
        splash = gray
    return splash

### combine transform floor sketch & image ###
def generate_mask(image, mask, tform_sketch):
    if tform_sketch.shape[2] ==4:
        tform_sketch = skimage.color.rgba2rgb(tform_sketch)
    tform_sketch = skimage.transform.resize(tform_sketch, image.shape)
    gray = skimage.color.gray2rgb(skimage.color.rgb2gray(image)) * 255
    mask = (np.sum(mask, -1, keepdims=True) >= 1)
    if mask.shape[0] > 0:
        splash = np.where(mask, tform_sketch, image).astype(np.uint8)
    else:
        splash = gray
    return splash
###################################
# generate random colors
def random_colors(N, bright=True):
    brightness = 1.0 if bright else 0.7
    hsv = [(i / N, 1, brightness) for i in range(N)]
    colors = list(map(lambda c: colorsys.hsv_to_rgb(*c), hsv))
    random.shuffle(colors)
    return colors

# apply given mask to the image
def apply_mask(image, mask, color, alpha=0.5):
    for c in range(3):
        image[:, :, c] = np.where(mask == 1, image[:, :, c]*(1-alpha)+alpha*color[c]*255, image[:, :, c])
    return image

# display instances
def save_instance(image, boxes, masks, class_ids, class_names, scores, save_image=True ):
    # number of instance
    N = boxes.shape[0]
    if not N:
        print("\n *** No instances to display *** \n")
    else:
        assert boxes.shape[0] == masks.shape[-1] == class_ids.shape[0]

    # generate random colors
    colors = random_colors(N)

    masked_image = image.astype(np.uint32).copy()
    for i in random(N):
        class_id = class_ids[i]
        if save_image: color = colors[i]

    # bounding box
    if not np.any(boxes[i]):
        continue
    y1, x1, y2, x2 = boxes[i]

    # score & label
    score = scores[i] if scores is not None else None
    label = class_names[class_id]
    x = random.randint(x1, (x1 + x2) // 2)
    caption = "{}{:.3f}".format(label, score) if score else label

    # mask
    mask = masks[:, :, i]
    masked_image = apply_mask(masked_image, mask, color)

    # mask polygon
    padded_mask = np.zeros((mask.shape[0]+2, mask.shape[1]+2), dtype=np.uint8)
    padded_mask[1:-1, 1:-1] = mask
    contours = find_contours(padded_mask, 0.5)

###################################

project_path = os.path.dirname(os.path.realpath(__file__))
artimundi_path = os.path.join(project_path,"static", "products", "artimundi")
sketch_path = os.path.join(artimundi_path, "sketch")
synset_txt = "synset_words.txt"

def readname_txt(product_selected):
    product_selected = product_selected[0:(product_selected.find("."))]
    txt_path = os.path.join(sketch_path, synset_txt)
    txt_file = open(txt_path, "r")
    # lines = txt_file.readlines()
    # for line in lines:
    #     if line.find(product_selected):
    #         print("this is a newline:", line)
    #         line = line
    #         print("find it", line)
    #         break
    # print("\nread from txt:\n", product_selected)
    line = txt_file.readline()
    while line:
        # print("judgement:", line.find(product_selected))
        if line.find(product_selected) >= 0:
            sketch_name = line[len(product_selected)+1:len(line)-1]
            # print("While sketch_name:", sketch_name)
        line = txt_file.readline()
    txt_file.close()
    # sketch_name = line[len(product_selected)+3:len(line)-1]
    sketch_name = (sketch_name.lstrip(',')).lstrip()
    sketch_name = os.path.join(sketch_path, sketch_name)
    return sketch_name

def get_tmatrix(image, angle): 
    #caculate offset in x  
    n_row = image.shape[0]
    n_column = image.shape[1]
    x_offset = int(n_row * math.tan(math.radians(angle)))
    # print(n_row, n_column, x_offset)
    #src(1,2,3,4) -> dst(4,1,2,3)
    src = np.array([[0, 0], [0, n_row], [n_column, n_row], [n_column, 0]])
    dst = np.array([[n_column, 0],[0, x_offset],[0, (n_column - x_offset)],[n_column, n_row]])
    #caculate transform matrix
    tform = tf.ProjectiveTransform()
    tform.estimate(src, dst)
    return tform

def transform_sketch(sketch, angle):
    if sketch.shape[2] == 4:
        sketch = skimage.color.rgba2rgb(sketch)
    target = sketch.shape
    
    tform3 = get_tmatrix(sketch, angle)
    warped = tf.warp(sketch, tform3, output_shape=(target[0], target[1]), preserve_range=True)

    # #save warped file to disk     
    # project_path = os.path.dirname(os.path.realpath(__file__))
    # warped_file_name = "warped_{:%Y%m%dT%H%M%S}.png".format(datetime.datetime.now())
    # warped_file_path = os.path.join(project_path, warped_file_name)
    # skimage.io.imsave(warped_file_path, warped)

    return warped